from sklearn.svm import OneClassSVM
import numpy as np
import json

class CustomOneClassSVM(OneClassSVM):
    def __init__(self, nu=0.5, kernel='rbf', degree=3, gamma='scale', coef0=0.0, tol=1e-3, shrinking=True, 
                 cache_size=200, verbose=False, max_iter=-1):
        super().__init__(nu=nu, kernel=kernel, degree=degree, gamma=gamma, coef0=coef0, tol=tol, 
                         shrinking=shrinking, cache_size=cache_size, verbose=verbose, max_iter=max_iter)

    def serialize(self):
        """将模型序列化为字典"""
        return {
            'params': self.get_params(),
            'support_': self.support_.tolist(),
            'support_vectors_': self.support_vectors_.tolist(),
            'dual_coef_': self.dual_coef_.tolist(),
            'intercept_': self.intercept_.tolist(),
            'n_support_': self.n_support_.tolist(),
            'offset_': self.offset_.tolist(),
            'shape_fit_': self.shape_fit_,
            '_sparse': self._sparse,
            '_n_support': self.n_support_.tolist()  # 添加 _n_support 属性
        }

    @classmethod
    def deserialize(cls, model_dict):
        """将字典反序列化为 OneClassSVM 模型"""
        model = cls(**model_dict['params'])
        attrs = model_dict
        
        # 确保所有属性都被正确设置
        model.support_ = np.array(attrs['support_'])
        model.support_vectors_ = np.array(attrs['support_vectors_'])
        model.dual_coef_ = np.array(attrs['dual_coef_'])
        model.intercept_ = np.array(attrs['intercept_'])
        model.offset_ = np.array(attrs['offset_'])
        model.shape_fit_ = attrs['shape_fit_']
        model._sparse = attrs['_sparse']
        
        # 设置 _n_support 属性
        model._n_support = np.array(attrs['_n_support'])
        
        # 重要：确保模型的内部状态一致
        model._validate_for_predict(model.support_vectors_)
        
        return model

if __name__ == '__main__':
    # 训练数据
    X = np.array([[1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [10, 10], [11, 11], [12, 12]])
    oc_svm = CustomOneClassSVM(nu=0.1, kernel='rbf', gamma=0.1)
    oc_svm.fit(X)

    # 序列化模型为 JSON 文件
    model_dict = oc_svm.serialize()
    with open('oc_svm.json', 'w') as f:
        json.dump(model_dict, f)

    # 反序列化模型
    with open('oc_svm.json', 'r') as f:
        loaded_model_dict = json.load(f)
    loaded_oc_svm = CustomOneClassSVM.deserialize(loaded_model_dict)

    # 预测新数据
    X_test = np.array([[1, 1], [3, 3], [11, 11], [13, 13]])
    try:
        y_pred = loaded_oc_svm.predict(X_test)
        print("预测结果:", y_pred)
    except ValueError as e:
        print("预测时出错:", e)